markdown-text-editor 2.0.0-beta.0 → 2.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -4
- package/dist/markdown-text-editor.css +1 -1
- package/dist/markdown-text-editor.es.js +858 -799
- package/dist/markdown-text-editor.es.js.map +1 -1
- package/dist/markdown-text-editor.min.js +67 -67
- package/dist/markdown-text-editor.min.js.map +1 -1
- package/dist/markdown-text-editor.umd.js +67 -67
- package/dist/markdown-text-editor.umd.js.map +1 -1
- package/locale/ar.js +55 -0
- package/locale/az.js +55 -0
- package/locale/bg.js +55 -0
- package/locale/bn.js +55 -0
- package/locale/bs.js +55 -0
- package/locale/ca.js +55 -0
- package/locale/cs.js +55 -0
- package/locale/da.js +55 -0
- package/locale/de.js +55 -0
- package/locale/el.js +55 -0
- package/locale/es.js +55 -0
- package/locale/et.js +55 -0
- package/locale/fa.js +55 -0
- package/locale/fi.js +55 -0
- package/locale/fil.js +55 -0
- package/locale/fr.js +55 -0
- package/locale/ga.js +55 -0
- package/locale/he.js +55 -0
- package/locale/hi.js +55 -0
- package/locale/hr.js +55 -0
- package/locale/hu.js +55 -0
- package/locale/hy.js +55 -0
- package/locale/id.js +55 -0
- package/locale/is.js +55 -0
- package/locale/it.js +55 -0
- package/locale/ja.js +55 -0
- package/locale/kn.js +55 -0
- package/locale/ko.js +55 -0
- package/locale/locale.d.ts +10 -0
- package/locale/lt.js +55 -0
- package/locale/lv.js +55 -0
- package/locale/mk.js +55 -0
- package/locale/mr.js +55 -0
- package/locale/ms.js +55 -0
- package/locale/mt.js +55 -0
- package/locale/nl.js +55 -0
- package/locale/no.js +55 -0
- package/locale/pl.js +55 -0
- package/locale/pt.js +55 -0
- package/locale/ro.js +55 -0
- package/locale/ru.js +55 -0
- package/locale/sk.js +55 -0
- package/locale/sl.js +55 -0
- package/locale/sq.js +55 -0
- package/locale/sr.js +55 -0
- package/locale/sv.js +55 -0
- package/locale/sw.js +55 -0
- package/locale/ta.js +55 -0
- package/locale/te.js +55 -0
- package/locale/template.js +62 -0
- package/locale/th.js +55 -0
- package/locale/tr.js +55 -0
- package/locale/uk.js +55 -0
- package/locale/ur.js +55 -0
- package/locale/uz.js +55 -0
- package/locale/vi.js +55 -0
- package/locale/zh-hk.js +55 -0
- package/locale/zh.js +55 -0
- package/package.json +22 -8
- package/types/index.d.ts +16 -5
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ A lightweight, embeddable JavaScript Markdown editor that transforms a standard
|
|
|
13
13
|
|
|
14
14
|
A native-first Markdown editor built on a standard textarea. No data binding, no API — just drop it in and your forms keep working as-is.
|
|
15
15
|
|
|
16
|
-
**Works standalone.** No Frutjam, no Tailwind, no framework required
|
|
16
|
+
**Works standalone.** No Frutjam, no Tailwind, no framework required. One script and one stylesheet.
|
|
17
17
|
|
|
18
18
|

|
|
19
19
|
|
|
@@ -40,7 +40,7 @@ Most JavaScript markdown editors (EasyMDE, SimpleMDE, CodeMirror-based editors)
|
|
|
40
40
|
| Swap the markdown parser | ✅ | ❌ |
|
|
41
41
|
| Keyboard shortcuts | ✅ | Partial |
|
|
42
42
|
| Dark mode / theming | ✅ | Limited |
|
|
43
|
-
| Bundle size, gzipped |
|
|
43
|
+
| Bundle size, gzipped | 57 KB (JS + CSS) | 107 KB (JS + CSS) |
|
|
44
44
|
|
|
45
45
|
## 🚀 Quick Start
|
|
46
46
|
|
|
@@ -90,6 +90,22 @@ Import the stylesheet **or** link it, never both. If you forget it entirely the
|
|
|
90
90
|
|
|
91
91
|
That's it. Form submission, `.value` access, and all native textarea behaviour work exactly as before.
|
|
92
92
|
|
|
93
|
+
### Upgrading from 1.x
|
|
94
|
+
|
|
95
|
+
**Add the stylesheet.** It used to be carried inside the JavaScript and injected as a `<style>` element. It is now a real file, so an existing setup keeps working but renders unstyled until you link or import it. The editor says so in the console rather than leaving you to guess.
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
import 'markdown-text-editor/style.css'; // bundlers
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/markdown-text-editor/dist/markdown-text-editor.css">
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If you load the editor from an unpinned CDN URL, this reaches you the moment 2.0.0 publishes. Pin a version if you are not ready.
|
|
106
|
+
|
|
107
|
+
That is the whole breaking change. `labels` was renamed to `locale` and still works under the old name, so nothing else needs touching.
|
|
108
|
+
|
|
93
109
|
## ✨ Features
|
|
94
110
|
|
|
95
111
|
- 🔌 **Native Form Integration** — Works exactly like a standard `<textarea>`. No complex APIs — just use `.value` or the `name` attribute. Compatible with Django, Laravel, PHP, Rails, Node.js, and with React or Vue via a ref and `destroy()` on unmount
|
|
@@ -106,12 +122,14 @@ That's it. Form submission, `.value` access, and all native textarea behaviour w
|
|
|
106
122
|
- 🛡️ **XSS Safe** — Preview output sanitized via [DOMPurify](https://github.com/cure53/DOMPurify) before rendering, including the output of a custom renderer
|
|
107
123
|
- 🛡️ **CSP Compatible** — No inline event handlers, no `eval`, and no injected `<style>` element. The stylesheet is a real file you link, so a strict policy needs no `'unsafe-inline'` exception for either `script-src` or `style-src` ([#42](https://github.com/nezanuha/markdown-text-editor/issues/42))
|
|
108
124
|
- 🌍 **RTL Support** — Native Right-to-Left support for Arabic, Urdu, Farsi, and other RTL languages
|
|
125
|
+
- 🗣️ **Translatable Interface** — Every tooltip, menu item, dialog field and screen reader name goes through the `locale` option, keyed by the English string. `locale/template.js` lists all 45 of them so you don't have to go looking. Fifty-six languages ship with the package; you import the one you need
|
|
109
126
|
- 🌙 **Dark Mode & Theming** — Inherits `data-theme` from any ancestor element. Built-in light, dark, snowberry, and darkberry themes. Fully customizable via CSS variables
|
|
110
127
|
- 🧩 **Custom Tools** — Add your own toolbar button with `{ custom: { title, icon, action } }`, or extend `MarkdownEditor.Tool` when it builds its own markup. Keyboard shortcuts, translation and teardown work exactly as they do for the built-ins. No fork, no patching
|
|
111
128
|
- 🎛️ **Modular Toolbar** — Pick exactly which tools appear and in what order
|
|
112
129
|
- 🟦 **TypeScript Ready** — Definitions ship with the package. Options, toolbar entries and variable shapes are all checked, so a mistyped tool name is a compile error rather than a silently missing button
|
|
130
|
+
- 🖥️ **SSR Safe** — Importing it on the server doesn't throw, so Next.js, Remix and Nuxt need no `dynamic(..., { ssr: false })` wrapper. The `<textarea>` is in the server HTML with its content, and the editor enhances it after hydration, so there's no markup mismatch and nothing pops in
|
|
113
131
|
- 📦 **Universal Module Support** — ESM, CommonJS, UMD, and IIFE. Works with Vite, webpack, Rollup, or directly via `<script src>` CDN — no configuration needed
|
|
114
|
-
- 🚀 **High Performance** — ~
|
|
132
|
+
- 🚀 **High Performance** — ~43KB gzipped JS plus ~14KB gzipped CSS, cached separately. Debounced preview, cached layout calculations, conflict-free Tab/Enter handling for large documents
|
|
115
133
|
|
|
116
134
|
## 🛠 Developer Workflow
|
|
117
135
|
|
|
@@ -189,6 +207,53 @@ new MarkdownEditor('#markdown-editor', { toolbar: ['bold', EmbedTool, 'preview']
|
|
|
189
207
|
|
|
190
208
|
Two helpers exist for tools that need them: `editor.renderMarkdown(md)` returns sanitized HTML exactly as the preview does, and `editor.createToolbar(textarea, ['bold', 'italic'])` builds a real toolbar bound to another textarea, for a tool collecting rich text in its own dialog.
|
|
191
209
|
|
|
210
|
+
### Translate the interface
|
|
211
|
+
|
|
212
|
+
Every tooltip, menu item, dialog field and screen reader name goes through the `locale` option, keyed by the English string. Anything you leave out stays in English.
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
import fr from 'markdown-text-editor/locale/fr.js';
|
|
216
|
+
|
|
217
|
+
new MarkdownEditor('#markdown-editor', { locale: fr });
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
`locale` takes the strings, not a language code. `locale: 'fr'` is a compile error in TypeScript and logs what to write instead in JavaScript. Importing the one language you want is why nobody downloads the other fifty-five.
|
|
221
|
+
|
|
222
|
+
<details>
|
|
223
|
+
<summary><strong>56 languages ship with the package</strong></summary>
|
|
224
|
+
|
|
225
|
+
`ar` Arabic · `az` Azerbaijani · `bg` Bulgarian · `bn` Bengali · `bs` Bosnian · `ca` Catalan · `cs` Czech · `da` Danish · `de` German · `el` Greek · `es` Spanish · `et` Estonian · `fa` Persian · `fi` Finnish · `fil` Filipino · `fr` French · `ga` Irish · `he` Hebrew · `hi` Hindi · `hr` Croatian · `hu` Hungarian · `hy` Armenian · `id` Indonesian · `is` Icelandic · `it` Italian · `ja` Japanese · `kn` Kannada · `ko` Korean · `lt` Lithuanian · `lv` Latvian · `mk` Macedonian · `mr` Marathi · `ms` Malay · `mt` Maltese · `nl` Dutch · `no` Norwegian · `pl` Polish · `pt` Portuguese · `ro` Romanian · `ru` Russian · `sk` Slovak · `sl` Slovenian · `sq` Albanian · `sr` Serbian · `sv` Swedish · `sw` Swahili · `ta` Tamil · `te` Telugu · `th` Thai · `tr` Turkish · `uk` Ukrainian · `ur` Urdu · `uz` Uzbek · `vi` Vietnamese · `zh` Chinese (Simplified) · `zh-hk` Chinese (Hong Kong)
|
|
226
|
+
|
|
227
|
+
English needs no file; it is what the editor falls back to.
|
|
228
|
+
|
|
229
|
+
None of these has been checked by a native speaker yet, so each file exports `reviewed = false` and says so in its header. If one reads wrong to you, [a pull request](https://github.com/nezanuha/markdown-text-editor/issues) correcting a single line is welcome and genuinely useful. Languages with more than one plural form, such as Polish and Arabic, currently get one wording that reads correctly for most counts but not all.
|
|
230
|
+
|
|
231
|
+
</details>
|
|
232
|
+
|
|
233
|
+
Partial is fine, and you can override a shipped translation without forking it:
|
|
234
|
+
|
|
235
|
+
```javascript
|
|
236
|
+
import fr from 'markdown-text-editor/locale/fr.js';
|
|
237
|
+
|
|
238
|
+
new MarkdownEditor('#markdown-editor', {
|
|
239
|
+
locale: { ...fr, 'Image': 'Photo' } // your wording wins
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**`locale/template.js` lists every string**, English on both sides. Copy it to add a language, or map it through a translation system you already have, which keeps the editor's wording consistent with the rest of your interface:
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
import template from 'markdown-text-editor/locale/template.js';
|
|
247
|
+
|
|
248
|
+
const locale = Object.fromEntries(
|
|
249
|
+
Object.keys(template).map(key => [key, i18n.t(`editor.${key}`)])
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
new MarkdownEditor('#markdown-editor', { locale });
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Counts carry a `{n}` placeholder, so `'{n} words'` can become `'{n} mots'` or `'mots : {n}'` and the number lands where that language wants it. CSS class names never change, so `.bold-btn` stays `.bold-btn` in every language.
|
|
256
|
+
|
|
192
257
|
### Tear down in SPAs
|
|
193
258
|
|
|
194
259
|
```javascript
|
|
@@ -199,8 +264,15 @@ editor.destroy();
|
|
|
199
264
|
In React, create the editor in an effect and return `destroy` as the cleanup — that also covers StrictMode running effects twice in development:
|
|
200
265
|
|
|
201
266
|
```jsx
|
|
267
|
+
// Options are read once, so reach the latest onChange through a ref rather
|
|
268
|
+
// than rebuilding the editor whenever the parent re-renders
|
|
269
|
+
const onChangeRef = useRef(onChange);
|
|
270
|
+
onChangeRef.current = onChange;
|
|
271
|
+
|
|
202
272
|
useEffect(() => {
|
|
203
|
-
const editor = new MarkdownEditor(ref.current, {
|
|
273
|
+
const editor = new MarkdownEditor(ref.current, {
|
|
274
|
+
onChange: (value) => onChangeRef.current?.(value),
|
|
275
|
+
});
|
|
204
276
|
return () => editor.destroy();
|
|
205
277
|
}, []);
|
|
206
278
|
```
|
|
@@ -209,6 +281,8 @@ Use `defaultValue`, not `value`. The editor writes to the textarea directly, so
|
|
|
209
281
|
|
|
210
282
|
The same two rules cover Svelte, Angular and anything else: don't bind the value, and call `destroy()` on unmount. In Angular, `onChange` fires outside the zone, so wrap it in `zone.run()` for change detection to notice.
|
|
211
283
|
|
|
284
|
+
This is also all you need for server-side rendering. `useEffect`, `onMounted` and `onMount` never run on the server, so the DOM work stays in the browser and importing the package server-side is safe. Next.js, Remix and Nuxt need no `ssr: false` wrapper, and the `<textarea>` ships in the server HTML with its content already in it.
|
|
285
|
+
|
|
212
286
|
Options are read once when the editor is constructed. Changing them later has no effect — destroy the editor and create a new one instead.
|
|
213
287
|
|
|
214
288
|
## 📖 Documentation
|